home *** CD-ROM | disk | FTP | other *** search
/ Network PC / Network PC.iso / amiga utilities / communication / bbs / termv4.6 / extras / source / gtlayout-source.lha / LT_Build.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-18  |  24.0 KB  |  1,002 lines

  1. /*
  2. **    GadTools layout toolkit
  3. **
  4. **    Copyright © 1993-1996 by Olaf `Olsen' Barthel
  5. **        Freely distributable.
  6. **
  7. **    :ts=4
  8. */
  9.  
  10. #ifndef _GTLAYOUT_GLOBAL_H
  11. #include "gtlayout_global.h"
  12. #endif
  13.  
  14. /*****************************************************************************/
  15.  
  16.  
  17. /****** gtlayout.library/LT_BuildA ******************************************
  18. *
  19. *   NAME
  20. *    LT_BuildA -- turn the user interface specs into a window
  21. *                 and gadgets.
  22. *
  23. *   SYNOPSIS
  24. *    Window = LT_BuildA(Handle,Tags);
  25. *      D0                 A0    A1
  26. *
  27. *    struct Window *LT_BuildA(LayoutHandle *,struct TagItem *);
  28. *
  29. *    Window = LT_Build(Handle,...);
  30. *
  31. *    struct Window *LT_Build(LayoutHandle *,...);
  32. *
  33. *   FUNCTION
  34. *    This is the big one. After building up a user interface specification
  35. *    using LT_NewA() a call to LT_BuildA() will finally lay out the single
  36. *    user interface elements, open a window and put the gadgets, etc.
  37. *    inside.
  38. *
  39. *    The code tries to fit all the gadgets into the window, but if it
  40. *    runs out of space it will fall back to a different font and
  41. *    rescale the user interface objects to match it. It will first
  42. *    fall back onto the system default font. If unsuccessful it will
  43. *    as a last resort try to use topaz.font/8.
  44. *
  45. *    To make it easier to distinguish between different handles that
  46. *    share the same Window->UserPort, the Window->UserData pointer
  47. *    will point to the LayoutHandle that created it (V13).
  48. *
  49. *        NOTE: Earlier library releases did not support this feature,
  50. *            so be prepared to deal with Window->UserData == NULL.
  51. *
  52. *   INPUTS
  53. *    Handle - Pointer to a LayoutHandle structure.
  54. *
  55. *    Tags - Pointer to TagItem list controlling window
  56. *        and layout attributes.
  57. *
  58. *
  59. *    All the tag values given are passed straight away to OpenWindowTags(),
  60. *    see intuition.doc for more information.
  61. *
  62. *    In addition to this a number of private tag values are supported:
  63. *
  64. *    LAWN_Menu (struct Menu *) - The menu to attach to the window, the
  65. *        IDCMP flags will be updated to include IDCMP_MENUPICK if this
  66. *        tag is used.
  67. *
  68. *    LAWN_MenuTemplate (struct NewMenu *) - A list of filled-in
  69. *        NewMenu structures which will get passed straight through
  70. *        to LT_NewMenuTemplate(). If a menu could be created, it will
  71. *        be attached to the window. LT_DeleteHandle() will then later
  72. *        automatically dispose of the menu. Please note that the window
  73. *        may fail to open due to the menu layout going wrong. Separate
  74. *        calls to LT_NewMenuTemplate() and LT_Build() may be a better
  75. *        approach since it is easier to find out which process went
  76. *        wrong. You will find a pointer to the menu attached to the
  77. *        LayoutHandle in LayoutHandle->Menu. Please note that this
  78. *        entry only exists in LayoutHandles created by gtlayout.library
  79. *        v13 or higher.
  80. *
  81. *            NOTE: This tag effectively overrides LAWN_Menu.
  82. *
  83. *        (requires gtlayout.library v13 or higher)
  84. *
  85. *    LAWN_MenuTags (struct TagItem *) - A list of TagItems which
  86. *        will get passed straight through to LT_NewMenuTagList().
  87. *        Even if you don't ask for it, LT_Build() will pass
  88. *        "LAMN_Handle,<Handle>" in for you, so any additional tags
  89. *        specifying screen, fonts, etc. will be overridden. If a menu
  90. *        could be created, it will be attached to the window.
  91. *        LT_DeleteHandle() will then later automatically dispose of the
  92. *        menu. Please note that the window may fail to open due to the
  93. *        menu layout going wrong. Separate calls to LT_NewMenuTagList()
  94. *        and LT_Build() may be a better approach since it is easier to
  95. *        find out which process went wrong. You will find a pointer to the
  96. *        menu attached to the LayoutHandle in LayoutHandle->Menu. Please note
  97. *        that this entry only exists in LayoutHandles created by
  98. *        gtlayout.library v13 or higher.
  99. *
  100. *            NOTE: This tag effectively overrides LAWN_Menu and has
  101. *                  precedence over LAWN_MenuTemplate.
  102. *
  103. *        (requires gtlayout.library v13 or higher)
  104. *
  105. *    LAWN_UserPort (struct MsgPort *) - The MsgPort to use as the
  106. *        window user port. The MsgPort will be attached using the
  107. *        common ModifyIDCMP() method, closing the window will
  108. *        first remove and reply all pending messages at this port.
  109. *
  110. *    LAWN_Left (LONG) - The left edge position the window is to use.
  111. *        This effectively overrides any horizontal alignment flags.
  112. *
  113. *            NOTE: the code may choose to ignore this value if it finds
  114. *                that the window will not fit onto the screen unless
  115. *                the left edge position is changed.
  116. *
  117. *    LAWN_Top (LONG) - The top edge position the window is to use.
  118. *        This effectively overrides any vertical alignment flags.
  119. *
  120. *            NOTE: the code may choose to ignore this value if it finds
  121. *                that the window will not fit onto the screen unless
  122. *                the top edge position is changed.
  123. *
  124. *    LAWN_Zoom (BOOL) - Adds a zoom gadget to the window. Clicking
  125. *        on this gadget will cause the window to shrink/zoom back
  126. *        to its original position. This differs from the WA_Zoom
  127. *        tag behaviour. When the window zooms back to its original
  128. *        position the gadgets are automatically refreshed.
  129. *        Default: FALSE
  130. *
  131. *    LAWN_MaxPen (LONG) - The maximum rendering pen index your code
  132. *        will use. Since you are -- with some restrictions -- allowed
  133. *        to render into the window created you may want to avoid
  134. *        silly side effects if drawing images or other colourful
  135. *        textures which do not share the common user interface colours.
  136. *        By default the layout code will change the maximum rendering
  137. *        pen number for the window to include only the user interface
  138. *        pen colours. This can, but need not disturb your own private
  139. *        window rendering.
  140. *        Look up graphics.library/SetMaxPen for more information.
  141. *        Default: determined by looking up Screen->DrawInfo.dri_Pens
  142. *
  143. *    LAWN_BelowMouse (BOOL) - This instructs the layout routine to
  144. *        centre the window created -- if possible -- below the
  145. *        mouse pointer. This effectively ignores any left edge,
  146. *        top edge or alignment settings.
  147. *        Default: FALSE
  148. *
  149. *    LAWN_MoveToWindow (BOOL) - When the window is finally open the
  150. *        user interface code will try to make sure the entire window
  151. *        is visible on the screen, this may involve moving the
  152. *        currently visible portion of an autoscrolling screen.
  153. *        Default: TRUE
  154. *
  155. *    LAWN_AutoRefresh (BOOL) - Handle IDCMP_REFRESHWINDOW events
  156. *        automatically.
  157. *        Default: TRUE
  158. *
  159. *    LAWN_HelpHook (struct Hook *) - Hook code to invoke when the user
  160. *        presses the "Help" key. See gtlayout.h for more information.
  161. *        Default: NULL
  162. *
  163. *    LAWN_Parent (struct Window *) - Parent window to centre the child
  164. *        window in.
  165. *        Default: NULL
  166. *
  167. *    LAWN_BlockParent (BOOL) - Lock the parent window via LT_LockWindow()
  168. *        until the child window is closed.
  169. *
  170. *            NOTE: requires LAWN_Parent attribute.
  171. *
  172. *        Default: FALSE
  173. *
  174. *    LAWN_SmartZoom (BOOL) - Attach a zoom gadget to the window created.
  175. *        When in zoomed state, the window will be as small as possible,
  176. *        showing only the window title and window gadgets:
  177. *
  178. *            NOTE: this tag implies LAWN_Zoom,TRUE
  179. *
  180. *        Default: FALSE
  181. *
  182. *    LAWN_Title (STRPTR) - The window title to use. Use this tag in
  183. *        place of WA_Title or you will break the layout code.
  184. *        Default: no title
  185. *
  186. *    LAWN_Bounds (struct IBox *) - Bounds to centre the window in.
  187. *        Default: NULL
  188. *
  189. *    LAWN_ExtraWidth (LONG) - Extra width to add into the calculation
  190. *        when opening the window.
  191. *        Default: 0
  192. *
  193. *    LAWN_ExtraHeight (LONG) - Extra height to add into the calculation
  194. *        when opening the window.
  195. *        Default: 0
  196. *
  197. *    LAWN_IDCMP (ULONG) - Use this tag in place of WA_IDCMP or you
  198. *        will break the object handling code.
  199. *
  200. *    LAWN_AlignWindow (UWORD) - Alignment information for the window, must
  201. *        be a mask made from the following bit values:
  202. *
  203. *            ALIGNF_RIGHT - Align to screen right edge
  204. *            ALIGNF_LEFT - Align to screen left edge
  205. *            ALIGNF_TOP - Align to screen top edge
  206. *            ALIGNF_BOTTOM - Align to screen bottom edge
  207. *
  208. *        Unless forbidden (such as by passing ALIGNF_RIGHT|ALIGNF_TOP)
  209. *        the window will be centered horizontally and/or vertically.
  210. *
  211. *    LAWN_FlushLeft (BOOL) - Add no horizontal space surrounding the
  212. *        objects the windows will hold.
  213. *        (requires gtlayout.library v10 or higher)
  214. *
  215. *    LAWN_FlushTop (BOOL) - Add no vertical space surrounding the
  216. *        objects the windows will hold.
  217. *        (requires gtlayout.library v10 or higher)
  218. *
  219. *    LAWN_Show (BOOL) - Make the window visible when it is opened;
  220. *        this may involve depth-arranging screens.
  221. *        (requires gtlayout.library v10 or higher)
  222. *
  223. *    LAWN_NoInitialRefresh (BOOL) - If set to TRUE, adds the
  224. *        gadgets, but does not draw the window imagery. You need
  225. *        to draw them later by calling gtlayout.library/LT_Refresh.
  226. *
  227. *   RESULT
  228. *    Window - Pointer to a Window structure.
  229. *
  230. *   SEE ALSO
  231. *       gtlayout.library/LT_Refresh
  232. *       intuition.library/OpenWindow
  233. *       intuition.library/OpenWindowTagList
  234. *
  235. ******************************************************************************
  236. *
  237. */
  238.  
  239. struct Window * LIBENT
  240. LT_BuildA(_REG(a0) LayoutHandle *handle,_REG(a1) struct TagItem *TagParams)
  241. {
  242.     ULONG             OpenWindowTag;
  243.     LONG             left, top, width, height;
  244.     LONG             OldLeft,OldTop,OldRight,OldBottom;
  245.     struct IBox         newBounds;
  246.     struct Menu        *menu;
  247.     struct TagItem    *item;
  248.     LONG             placeLeft;
  249.     LONG             placeTop;
  250.     struct IBox         zoomBox;
  251.     struct IBox        *zoom;
  252.     struct TextFont *font;
  253.     struct TagItem    *NewTags,*Tags;
  254.     struct Window    *Parent;
  255.     STRPTR             title;
  256.     struct IBox        *bounds;
  257.     LONG             extraWidth,
  258.                      extraHeight;
  259.     ULONG             IDCMP;
  260.     LONG             align;
  261.     LONG             MinX,
  262.                      MinY,
  263.                      MaxX,
  264.                      MaxY;
  265.     ULONG             BorderBottom,
  266.                      BorderRight;
  267.     struct Menu        *LocalMenu;
  268.     struct TagItem    *LocalMenuTags;
  269.     struct NewMenu    *LocalMenuTemplate;
  270.     BOOL             SizeGadget,
  271.                      SizeBRight,
  272.                      SizeBBottom;
  273.     BOOL              BlockParent,
  274.                      SmartZoom,
  275.                      MakeVisible;
  276.     BOOL             DontRefresh;
  277.  
  278.     if(!handle)
  279.         return(NULL);
  280.  
  281.     menu                = NULL;
  282.     NewTags                = NULL;
  283.     Parent                = handle->Parent;
  284.     title                = NULL;
  285.     bounds                 = NULL;
  286.     extraWidth            = 0,
  287.     extraHeight            = 0;
  288.     IDCMP                = NULL;
  289.     align                = 0;
  290.     LocalMenu            = NULL;
  291.     LocalMenuTags        = NULL;
  292.     LocalMenuTemplate    = NULL;
  293.     SizeGadget            = FALSE,
  294.     SizeBRight            = FALSE,
  295.     SizeBBottom            = FALSE;
  296.     BlockParent            = handle->BlockParent,
  297.     SmartZoom            = FALSE,
  298.     MakeVisible            = FALSE;
  299.     DontRefresh            = FALSE;
  300.  
  301.     /* ALWAYS */
  302.     {
  303.         struct TagItem *TagList = (struct TagItem *)TagParams;
  304.  
  305.         while(item = NextTagItem(&TagList))
  306.         {
  307.             switch((ULONG)item->ti_Tag)
  308.             {
  309.                 case LAWN_NoInitialRefresh:
  310.  
  311.                     DontRefresh = item->ti_Data;
  312.                     break;
  313.  
  314.                 case LAWN_MenuTemplate:
  315.  
  316.                     LocalMenuTemplate = (struct NewMenu *)item->ti_Data;
  317.                     break;
  318.  
  319.                 case LAWN_MenuTags:
  320.  
  321.                     LocalMenuTags = (struct TagItem *)item->ti_Data;
  322.                     break;
  323.  
  324.                 case LAWN_FlushLeft:
  325.  
  326.                     handle->FlushLeft = item->ti_Data;
  327.                     break;
  328.  
  329.                 case LAWN_FlushTop:
  330.  
  331.                     handle->FlushTop = item->ti_Data;
  332.                     break;
  333.  
  334.                 case LAWN_TitleText:
  335.  
  336.                     title = (STRPTR)item->ti_Data;
  337.                     break;
  338.  
  339.                 case LAWN_TitleID:
  340.  
  341.                     if(!handle->LocaleHook)
  342.                         return(NULL);
  343.                     else
  344.                         title = (STRPTR)CallHookPkt(handle->LocaleHook,handle,(APTR)item->ti_Data);
  345.  
  346.                     break;
  347.  
  348.                 case LAWN_Bounds:
  349.  
  350.                     bounds = (struct IBox *)item->ti_Data;
  351.                     break;
  352.  
  353.                 case LAWN_ExtraWidth:
  354.  
  355.                     extraWidth = item->ti_Data;
  356.                     break;
  357.  
  358.                 case LAWN_ExtraHeight:
  359.  
  360.                     extraHeight = item->ti_Data;
  361.                     break;
  362.  
  363.                 case LAWN_IDCMP:
  364.  
  365.                     IDCMP = item->ti_Data;
  366.                     break;
  367.  
  368.                 case LAWN_AlignWindow:
  369.  
  370.                     align = item->ti_Data;
  371.                     break;
  372.             }
  373.         }
  374.     }
  375.  
  376. #ifdef DO_MENUS
  377.     if(LocalMenuTags)
  378.     {
  379.         if(LocalMenu = LT_NewMenuTags(LAMN_Handle,handle,TAG_MORE,LocalMenuTags))
  380.         {
  381.             menu = LocalMenu;
  382.             handle->IDCMP |= IDCMP_MENUPICK;
  383.         }
  384.         else
  385.             return(NULL);
  386.     }
  387.     else
  388.     {
  389.         if(LocalMenuTemplate)
  390.         {
  391.             if(LocalMenu = LT_NewMenuTemplate(handle->Screen,handle->TextAttr,handle->AmigaGlyph,handle->CheckGlyph,NULL,LocalMenuTemplate))
  392.             {
  393.                 menu = LocalMenu;
  394.                 handle->IDCMP |= IDCMP_MENUPICK;
  395.             }
  396.             else
  397.                 return(NULL);
  398.         }
  399.     }
  400. #endif    // DO_MENUS
  401.  
  402.     if(!bounds)
  403.     {
  404.         LTP_GetDisplayClip(handle->Screen,&newBounds.Left,&newBounds.Top,&newBounds.Width,&newBounds.Height);
  405.  
  406.         bounds = &newBounds;
  407.     }
  408.  
  409.     left = handle->Screen->WBorLeft;
  410.  
  411.     if(title)
  412.         top = handle->Screen->WBorTop + handle->Screen->Font->ta_YSize + 1;
  413.     else
  414.         top = handle->Screen->WBorTop;
  415.  
  416.     BorderRight        = handle->Screen->WBorRight;
  417.     BorderBottom    = handle->Screen->WBorBottom;
  418.  
  419.     if(handle->ResizeView)
  420.     {
  421.         if(handle->ResizeView->Special.List.ResizeY)
  422.             BorderBottom = LTP_GetSizeHeight(handle);
  423.         else
  424.         {
  425.             if(handle->ResizeView->Special.List.ResizeX)
  426.                 BorderRight = LTP_GetSizeWidth(handle);
  427.         }
  428.     }
  429.  
  430.     OldLeft        = left;
  431.     OldRight    = BorderRight;
  432.     OldTop        = top;
  433.     OldBottom    = BorderBottom;
  434.  
  435.     if(!handle->FlushLeft)
  436.     {
  437.         left        += handle->InterWidth;
  438.         BorderRight    += handle->InterWidth;
  439.     }
  440.  
  441.     if(!handle->FlushTop)
  442.     {
  443.         top                += handle->InterHeight;
  444.         BorderBottom    += handle->InterHeight;
  445.     }
  446.  
  447.     LTP_CreateGadgets(handle,bounds,left,top,left + BorderRight,top + BorderBottom);
  448.  
  449.     if(handle->Failed)
  450.         return(NULL);
  451.  
  452.         // In case the font got changed we'll have to redo it all again.
  453.         // Just to be sure, we do it all over again.
  454.  
  455.     left            = OldLeft;
  456.     BorderRight        = OldRight;
  457.     top                = OldTop;
  458.     BorderBottom    = OldBottom;
  459.  
  460.     if(!handle->FlushLeft)
  461.     {
  462.         left        += handle->InterWidth;
  463.         BorderRight    += handle->InterWidth;
  464.     }
  465.  
  466.     if(!handle->FlushTop)
  467.     {
  468.         top                += handle->InterHeight;
  469.         BorderBottom    += handle->InterHeight;
  470.     }
  471.  
  472.     width    = left + handle->TopGroup->Width + BorderRight;
  473.     height    = top + handle->TopGroup->Height + BorderBottom;
  474.  
  475.     if(handle->ResizeView)
  476.     {
  477.         LONG GlyphWidth,GlyphHeight;
  478.  
  479.         MaxX = MinX = width;
  480.         MaxY = MinY = height;
  481.  
  482.         if(handle->ResizeView->Special.List.ResizeX)
  483.             MaxX = handle->Screen->Width;
  484.  
  485.         if(handle->ResizeView->Special.List.ResizeY)
  486.         {
  487.             MaxY = handle->Screen->Height;
  488.  
  489.             SizeBBottom = TRUE;
  490.         }
  491.         else
  492.             SizeBRight = TRUE;
  493.  
  494.         SizeGadget = TRUE;
  495.  
  496.         if(handle->ResizeView->Special.List.TextAttr)
  497.         {
  498.             GlyphWidth    = handle->ResizeView->Special.List.FixedGlyphWidth;
  499.             GlyphHeight    = handle->ResizeView->Special.List.FixedGlyphHeight;
  500.         }
  501.         else
  502.         {
  503.             GlyphWidth    = handle->GlyphWidth;
  504.             GlyphHeight    = handle->GlyphHeight;
  505.         }
  506.  
  507.         if(handle->ResizeView->Special.List.MinChars && handle->ResizeView->Special.List.MinChars < handle->ResizeView->Chars)
  508.             MinX -= GlyphWidth * (handle->ResizeView->Chars - handle->ResizeView->Special.List.MinChars);
  509.  
  510.         if(handle->ResizeView->Special.List.MinLines && handle->ResizeView->Special.List.MinChars < handle->ResizeView->Lines)
  511.             MinY -= GlyphHeight * (handle->ResizeView->Lines - handle->ResizeView->Special.List.MinLines);
  512.     }
  513.     else
  514.     {
  515.         MaxX = MinX = width;
  516.         MaxY = MinY = height;
  517.     }
  518.  
  519.     if(align & ALIGNF_LEFT)
  520.         placeLeft = 0;
  521.     else
  522.     {
  523.         if(align & ALIGNF_RIGHT)
  524.             placeLeft = bounds->Width - (width + extraWidth);
  525.         else
  526.             placeLeft = (bounds->Width - (width + extraWidth)) / 2;
  527.     }
  528.  
  529.     if(align & ALIGNF_TOP)
  530.         placeTop = 0;
  531.     else
  532.     {
  533.         if(align & ALIGNF_BOTTOM)
  534.             placeTop = bounds->Height - (height + extraHeight);
  535.         else
  536.             placeTop = (bounds->Height - (height + extraHeight)) / 2;
  537.     }
  538.  
  539.     if(align & ALIGNF_EXTRA_LEFT)
  540.         placeLeft += extraWidth;
  541.     else
  542.     {
  543.         if(!(align & ALIGNF_EXTRA_RIGHT))
  544.             placeLeft += extraWidth / 2;
  545.     }
  546.  
  547.     if(align & ALIGNF_EXTRA_TOP)
  548.         placeTop += extraHeight;
  549.     else
  550.     {
  551.         if(!(align & ALIGNF_EXTRA_BOTTOM))
  552.             placeTop += extraHeight / 2;
  553.     }
  554.  
  555.     placeLeft    += bounds->Left;
  556.     placeTop    += bounds->Top;
  557.  
  558.     if(placeLeft < 0)
  559.         placeLeft = 0;
  560.  
  561.     if(placeTop < 0)
  562.         placeTop = 0;
  563.  
  564.     zoom = NULL;
  565.  
  566.     handle->AutoRefresh = TRUE;
  567.  
  568. #ifdef DO_CLONING
  569.     if(handle->CloneExtra)
  570.     {
  571.         placeLeft    = 0;
  572.         placeTop    = handle->CloneExtra->Screen->BarHeight + 1;
  573.  
  574.         zoomBox.Left    = placeLeft;
  575.         zoomBox.Top        = placeTop;
  576.     }
  577. #endif    /* DO_CLONING */
  578.  
  579.     /* ALWAYS */
  580.     {
  581.         struct TagItem *TagList = (struct TagItem *)TagParams;
  582.  
  583.         while(item = NextTagItem(&TagList))
  584.         {
  585.             switch((ULONG)item->ti_Tag)
  586.             {
  587.                 case LA_Menu:
  588.  
  589.                     if(!menu)
  590.                     {
  591.                         handle->IDCMP |= IDCMP_MENUPICK;
  592.  
  593.                         menu = (struct Menu *)item->ti_Data;
  594.                     }
  595.  
  596.                     break;
  597.  
  598.                 case LAWN_SmartZoom:
  599.  
  600.                     if(!(SmartZoom = item->ti_Data))
  601.                         break;
  602.  
  603.                 case LAWN_Zoom:
  604.  
  605.                     if(item->ti_Data)
  606.                     {
  607.                         if(title && SmartZoom)
  608.                         {
  609.                             STATIC UWORD WhichTable[3] =
  610.                             {
  611.                                 CLOSEIMAGE,
  612.                                 ZOOMIMAGE,
  613.                                 DEPTHIMAGE
  614.                             };
  615.  
  616.                             LONG     Size = 0,i;
  617.                             LONG     SizeType;
  618.                             Object    *Image;
  619.                             BOOL     GotIt = TRUE;
  620.  
  621.                             if(handle->Screen->Flags & SCREENHIRES)
  622.                                 SizeType = SYSISIZE_MEDRES;
  623.                             else
  624.                                 SizeType = SYSISIZE_LOWRES;
  625.  
  626.                             for(i = 0 ; i < 3 ; i++)
  627.                             {
  628.                                 if(Image = NewObject(NULL,SYSICLASS,
  629.                                     SYSIA_Size,        SizeType,
  630.                                     SYSIA_Which,    WhichTable[i],
  631.                                     SYSIA_DrawInfo, handle->DrawInfo,
  632.                                 TAG_DONE))
  633.                                 {
  634.                                     ULONG Width;
  635.  
  636.                                     GetAttr(IA_Width,Image,&Width);
  637.  
  638.                                     Size += Width;
  639.  
  640.                                     DisposeObject(Image);
  641.                                 }
  642.                                 else
  643.                                     GotIt = FALSE;
  644.                             }
  645.  
  646.                             if(GotIt)
  647.                             {
  648.                                 Size += 8 + TextLength(&handle->Screen->RastPort,title,strlen(title)) + 8;
  649.  
  650.                                 zoomBox.Width = Size;
  651.                             }
  652.                             else
  653.                                 zoomBox.Width = width;
  654.                         }
  655.                         else
  656.                             zoomBox.Width = width;
  657.  
  658.                         if(V39)
  659.                         {
  660.                             zoomBox.Left    = -1;
  661.                             zoomBox.Top        = -1;
  662.                         }
  663.                         else
  664.                         {
  665.                             zoomBox.Left    = placeLeft;
  666.                             zoomBox.Top        = placeTop;
  667.                         }
  668.  
  669.                         zoomBox.Height = handle->Screen->WBorTop + handle->Screen->Font->ta_YSize + 1;
  670.  
  671.                         zoom = &zoomBox;
  672.                     }
  673.  
  674.                     break;
  675.  
  676.                 case LAWN_UserPort:
  677.  
  678.                     handle->MsgPort = (struct MsgPort *)item->ti_Data;
  679.                     break;
  680.  
  681.                 case LAWN_HelpHook:
  682.  
  683.                     handle->HelpHook = (struct Hook *)item->ti_Data;
  684.                     break;
  685.  
  686.                 case LAWN_Left:
  687.  
  688.                     placeLeft = item->ti_Data;
  689.                     break;
  690.  
  691.                 case LAWN_Top:
  692.  
  693.                     placeTop = item->ti_Data;
  694.                     break;
  695.  
  696.                 case LAWN_Parent:
  697.  
  698.                     Parent = (struct Window *)item->ti_Data;
  699.                     break;
  700.  
  701.                 case LAWN_BlockParent:
  702.  
  703.                     BlockParent = item->ti_Data;
  704.                     break;
  705.  
  706.                 case LAWN_BelowMouse:
  707.  
  708.                     if((placeLeft = handle->Screen->MouseX - (width / 2)) < 0)
  709.                         placeLeft = 0;
  710.  
  711.                     if((placeTop = handle->Screen->MouseY - (height / 2)) < 0)
  712.                         placeTop = 0;
  713.  
  714.                     break;
  715.  
  716.                 case LAWN_MaxPen:
  717.  
  718.                     handle->MaxPen = (LONG)item->ti_Data;
  719.                     break;
  720.  
  721.                 case LAWN_MoveToWindow:
  722.  
  723.                     handle->MoveToWindow = (LONG)item->ti_Data;
  724.                     break;
  725.  
  726.                 case LAWN_AutoRefresh:
  727.  
  728.                     handle->AutoRefresh = (LONG)item->ti_Data;
  729.                     break;
  730.  
  731.                 case LAWN_Show:
  732.  
  733.                     MakeVisible = item->ti_Data;
  734.                     break;
  735.             }
  736.         }
  737.     }
  738.  
  739.     Tags = (struct TagItem *)TagParams;
  740.  
  741.     if(handle->BackgroundPen && !V39)
  742.     {
  743.         if(NewTags = CloneTagItems(Tags))
  744.         {
  745.             STATIC Tag Filter[] = { WA_SimpleRefresh,TAG_DONE };
  746.  
  747.             FilterTagItems(NewTags,Filter,TAGFILTER_NOT);
  748.  
  749.             Tags = NewTags;
  750.         }
  751.         else
  752.         {
  753. #ifdef DO_MENUS
  754.             LT_DisposeMenu(LocalMenu);
  755. #endif    // DO_MENUS
  756.             return(NULL);
  757.         }
  758.     }
  759.  
  760.     if(Parent)
  761.     {
  762.         WORD    Left,Top,Width,Height;
  763.         LONG    MoveLeft,MoveTop,WindowLeft,WindowTop,WindowWidth,WindowHeight;
  764.  
  765.         WindowLeft        = Parent->LeftEdge + Parent->BorderLeft;
  766.         WindowTop        = Parent->TopEdge + Parent->BorderTop;
  767.         WindowWidth        = Parent->Width - (Parent->BorderLeft + Parent->BorderRight);
  768.         WindowHeight    = Parent->Height - (Parent->BorderTop + Parent->BorderBottom);
  769.  
  770.         LTP_GetDisplayClip(Parent->WScreen,&Left,&Top,&Width,&Height);
  771.  
  772.         if((MoveLeft = WindowLeft + (WindowWidth - width) / 2) < 0)
  773.             MoveLeft = 0;
  774.  
  775.         if((MoveTop = WindowTop + (WindowHeight - height) / 2) < 0)
  776.             MoveTop = 0;
  777.  
  778.         if(MoveLeft < Left || MoveLeft + width > Left + Width)
  779.             MoveLeft = -1;
  780.  
  781.         if(MoveTop < Top || MoveTop + height > Top + Height)
  782.             MoveTop = -1;
  783.  
  784.         if(MoveTop != -1 && MoveLeft != -1)
  785.         {
  786.             placeLeft    = MoveLeft;
  787.             placeTop    = MoveTop;
  788.         }
  789.     }
  790.  
  791.     if(BlockParent && Parent)
  792.     {
  793.         LT_LockWindow(Parent);
  794.  
  795.         handle->Parent = Parent;
  796.     }
  797.  
  798.     if(SizeGadget)
  799.         zoom = NULL;
  800.  
  801.     if(handle->Screen == handle->PubScreen)
  802.         OpenWindowTag = handle->WA_ScreenTag;
  803.     else
  804.         OpenWindowTag = WA_CustomScreen;
  805.  
  806.     if(handle->Window = OpenWindowTags(NULL,
  807.         WA_Left,            placeLeft,
  808.         WA_Top,             placeTop,
  809.         WA_Width,            width,
  810.         WA_Height,            height,
  811.         WA_NewLookMenus,    TRUE,
  812.         OpenWindowTag,        handle->Screen,
  813.         WA_MinWidth,        MinX,
  814.         WA_MinHeight,        MinY,
  815.         WA_MaxWidth,        MaxX,
  816.         WA_MaxHeight,        MaxY,
  817.         WA_SizeGadget,        SizeGadget,
  818.         WA_SizeBBottom,        SizeBBottom,
  819.         WA_SizeBRight,        SizeBRight,
  820.         WA_PointerDelay,    TRUE,
  821.         WA_BusyPointer,        TRUE,
  822.  
  823.         zoom ? WA_Zoom : TAG_IGNORE,                        zoom,
  824.         !handle->MsgPort ? WA_IDCMP : TAG_IGNORE,            IDCMP_REFRESHWINDOW | IDCMP_RAWKEY | IDCMP_ACTIVEWINDOW | IDCMP_INACTIVEWINDOW | IDCMP_MOUSEBUTTONS | IDCMP_CHANGEWINDOW | IDCMP | handle->IDCMP,
  825.         title ? WA_Title : TAG_IGNORE,                        title,
  826.         handle->AmigaGlyph ? WA_AmigaKey : TAG_IGNORE,        handle->AmigaGlyph,
  827.         handle->CheckGlyph ? WA_Checkmark : TAG_IGNORE,        handle->CheckGlyph,
  828.         handle->BackgroundPen ? WA_BackFill : TAG_IGNORE,    &handle->BackfillHook,
  829.     TAG_MORE,Tags))
  830.     {
  831.         font = handle->RPort.Font;
  832.  
  833.         handle->RPort = *handle->Window->RPort;
  834.  
  835.         LTP_SetFont(handle,font);
  836.  
  837.         if(V39 && handle->MaxPen > 0)
  838.         {
  839.             SetMaxPen(&handle->RPort,handle->MaxPen);
  840.             SetMaxPen(handle->Window->RPort,handle->MaxPen);
  841.         }
  842.  
  843.         if(NewTags)
  844.         {
  845.             FreeTagItems(NewTags);
  846.             NewTags = NULL;
  847.         }
  848.  
  849.             // It's really that simple...
  850.  
  851.         if(DontRefresh)
  852.             LTP_AddGadgetsDontRefresh(handle);
  853.         else
  854.             LTP_AddGadgets(handle);
  855.  
  856.         handle->Window->UserData = (APTR)handle;
  857.  
  858.         if(handle->MsgPort)
  859.         {
  860.             handle->Window->UserPort = handle->MsgPort;
  861.  
  862.             if(!ModifyIDCMP(handle->Window,IDCMP_CHANGEWINDOW | IDCMP_REFRESHWINDOW | IDCMP_RAWKEY | IDCMP_INACTIVEWINDOW | IDCMP_ACTIVEWINDOW | IDCMP_MOUSEBUTTONS | IDCMP | handle->IDCMP))
  863.             {
  864.                 handle->Window->UserPort = NULL;
  865.  
  866.                 return (NULL);
  867.             }
  868.         }
  869.  
  870.         if(menu)
  871.             SetMenuStrip(handle->Window,menu);
  872.  
  873.         handle->Menu = LocalMenu;
  874.  
  875.         LTP_SelectInitialActiveGadget(handle);
  876. #ifdef DO_CLONING
  877.         if(handle->CloneExtra)
  878.             ScreenToFront(handle->Window->WScreen);
  879. #endif
  880.         if(V39)
  881.             SetWindowPointerA(handle->Window,NULL);
  882.  
  883.         if(MakeVisible)
  884.             ScreenToFront(handle->Screen);
  885.  
  886.         if(handle->MoveToWindow || MakeVisible)
  887.             LTP_MoveToWindow(handle);
  888.  
  889.         if((handle->Window->Flags & WFLG_WINDOWACTIVE) && handle->ActiveString && !DontRefresh)
  890.             LT_Activate(handle,handle->ActiveString->ID);
  891.     }
  892.     else
  893.     {
  894.         if(handle->Parent)
  895.         {
  896.             LT_UnlockWindow(handle->Parent);
  897.  
  898.             handle->Parent = NULL;
  899.         }
  900.  
  901. #ifdef DO_MENUS
  902.         LT_DisposeMenu(LocalMenu);
  903. #endif    // DO_MENUS
  904.     }
  905.  
  906.     FreeTagItems(NewTags);
  907.  
  908.     return(handle->Window);
  909. }
  910.  
  911.  
  912. /*****************************************************************************/
  913.  
  914.  
  915. VOID
  916. LTP_SelectInitialActiveGadget(LayoutHandle *Handle)
  917. {
  918.     ObjectNode *Node;
  919.     LONG i;
  920.  
  921.     Handle->Previous = NULL;
  922.  
  923.     for(i = 0 ; i < Handle->Count ; i++)
  924.     {
  925.         if(Handle->GadgetArray[i])
  926.         {
  927.             if(GETOBJECT(Handle->GadgetArray[i],Node))
  928.             {
  929.                 if(LIKE_STRING_KIND(Node) || (Node->Type == INTEGER_KIND))
  930.                 {
  931.                     Handle->Previous = Handle->GadgetArray[i];
  932.                     break;
  933.                 }
  934.             }
  935.         }
  936.     }
  937. }
  938.  
  939.  
  940. /*****************************************************************************/
  941.  
  942.  
  943. struct Window * __stdargs
  944. LT_Layout(LayoutHandle *handle,STRPTR title,struct IBox *bounds,LONG extraWidth,LONG extraHeight,ULONG IDCMP,LONG align,...)
  945. {
  946.     struct Window *Result;
  947.     va_list VarArgs;
  948.  
  949.     va_start(VarArgs,align);
  950.  
  951.     Result = LT_Build(handle,
  952.         LAWN_Title,            title,
  953.         LAWN_Bounds,        bounds,
  954.         LAWN_ExtraWidth,    extraWidth,
  955.         LAWN_ExtraHeight,    extraHeight,
  956.         LAWN_IDCMP,            IDCMP,
  957.         LAWN_AlignWindow,    align,
  958.     TAG_MORE,(struct TagItem *)VarArgs);
  959.  
  960.     va_end(VarArgs);
  961.  
  962.     return(Result);
  963. }
  964.  
  965.  
  966. /*****************************************************************************/
  967.  
  968.  
  969. struct Window * LIBENT
  970. LT_LayoutA(_REG(a0) LayoutHandle *handle,_REG(a1) STRPTR title,_REG(a2) struct IBox *bounds,_REG(d0) LONG extraWidth,_REG(d1) LONG extraHeight,_REG(d2) ULONG IDCMP,_REG(d3) LONG align,_REG(a3) struct TagItem *TagParams)
  971. {
  972.     struct Window *Result;
  973.  
  974.     Result = LT_Build(handle,
  975.         LAWN_Title,            title,
  976.         LAWN_Bounds,        bounds,
  977.         LAWN_ExtraWidth,    extraWidth,
  978.         LAWN_ExtraHeight,    extraHeight,
  979.         LAWN_IDCMP,            IDCMP,
  980.         LAWN_AlignWindow,    align,
  981.     TAG_MORE,TagParams);
  982.  
  983.     return(Result);
  984. }
  985.  
  986.  
  987. /*****************************************************************************/
  988.  
  989.  
  990. struct Window * __stdargs
  991. LT_Build(LayoutHandle *Handle,...)
  992. {
  993.     struct Window *Result;
  994.     va_list VarArgs;
  995.  
  996.     va_start(VarArgs,Handle);
  997.     Result = LT_BuildA(Handle,(struct TagItem *)VarArgs);
  998.     va_end(VarArgs);
  999.  
  1000.     return(Result);
  1001. }
  1002.